/****************************************************************************
*
* Description: File loader
* Module: 'source_manager.h'
* Created at: 20.11.06 02:15:30 UTC
*
* $Revision$
*
****************************************************************************/
#pragma once

#if !defined(__STORAGE_SOURCE_MANAGER_H__)
#define __STORAGE_SOURCE_MANAGER_H__

#include <list>
#include <string>
#include <boost/shared_ptr.hpp>
#include <common/singleton.h>
#include <storage/storage.h>
#include <storage/source.h>

namespace storage {

template <
	class item_T,
	class container_T = std::list < item_T >
	>
class basic_source_manager
{
public:
	typedef item_T		item_t;
    typedef container_T	container_t;

    virtual ~basic_source_manager()
    {}

    container_t & sources()
    {
    	return sources_;
    }

protected:
    /* collection of available sources.  */
    container_t sources_;
};

typedef basic_source_manager< boost::shared_ptr<source> > source_manager_t;
typedef common::singleton< source_manager_t > source_manager;

#define	SOURCES \
	storage::source_manager::instance()


template < class container_T >
class collect_valid_by_name
{
public:
	collect_valid_by_name(std::string & src):
        source_(src)
    {}

	void operator()(source_manager_t::item_t & val)
    {
        val->name().assign(source_);
		val->read();
        if( val->is_valid() )
            valid_.push_back(val);

		source_manager_t::item_t::value_type::container_t empty;
		val->data().swap(empty);
    }

    container_T result()
    {
        return valid_;
    }

private:
	std::string	source_;
    container_T	valid_;
};

template < class container_T >
class collect_valid_by_data
{
public:
	collect_valid_by_data(storage_t & src):
        source_(src)
    {}

	void operator()(source_manager_t::item_t & val)
    {
		*val = source_;
        if( val->is_valid() )
            valid_.push_back(val);
    }

    container_T result()
    {
        return valid_;
    }

private:
	storage_t	source_;
    container_T	valid_;
};

template < class container_T >
container_T get_valid_for(container_T & sources, std::string & filename)
{
    return for_each(sources.begin(), sources.end(), collect_valid_by_name<container_T>(filename)).result();
}

template < class container_T >
container_T get_valid_for(container_T & sources, storage_t & data)
{
    return for_each(sources.begin(), sources.end(), collect_valid_by_data<container_T>(data)).result();
}

} /* End of sources.  */

#endif  /* End of __STORAGE_SOURCE_MANAGER_H__.  */
